package com.heimali.happyreader;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.heimali.happyreader.config.Constants;
import com.heimali.happyreader.config.PersonalConfig;
import com.heimali.happyreader.db.dao.ListDao;
import com.heimali.happyreader.debug.Console;
import com.heimali.happyreader.model.Intro;
import com.heimali.happyreader.ui.PullToRefreshListView;
import com.heimali.happyreader.utils.ErrorUtils;
import com.heimali.happyreader.utils.HttpUtils;
import com.heimali.happyreader.utils.LogicUtils;
import com.heimali.happyreader.utils.NetUtils;
import com.heimali.happyreader.wraper.ArticleListWraper;
import com.heimali.happyreader.wraper.BaseWraper;

public class ArticleListActivity extends BaseActivity implements View.OnClickListener {

	public final String TAG = "ArticleListActivity";
	private Button rightButton;
	private Button refreshButton;
	private Button moreButton;
	private ArticleListAdapter adapter;
	private PullToRefreshListView articleListView;

	private boolean isAutoRefresh;
	private int curMinID = -1; // 当前显示的列表中的最小ID
	private int curMaxID = 0;

	Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			default:
				break;
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// checkLogin();
		initView();
		initProgressBar();
		isAutoRefresh = PersonalConfig.getInstance().getConfig(Constants.PERSONAL_CONFIG_IS_AUTO_REFRESH, false);
		initData();
		autoCheckNewVersion();
	}

	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.right_btn:
		case R.id.refresh:
		case R.id.progress_bar_retry:
		case R.id.no_article_list_refresh:
			getRecentData(true);
			break;
		case R.id.article_list_more:
			getEarlyData();
			break;
		}
	}

	private void initView() {
		setContentView(R.layout.article_list);
		adapter = new ArticleListAdapter(ArticleListActivity.this, null);
		articleListView = (PullToRefreshListView) findViewById(R.id.article_list);
		articleListView.setAdapter(adapter);
		articleListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				int articleID = adapter.getDataSources().get((int) id).id;
				Intent intent = new Intent(ArticleListActivity.this, ArticleActivity.class);
				intent.putExtra("articleID", articleID);
				startActivity(intent);
			}
		});
		articleListView.setOnRefreshListener(new PullToRefreshListView.OnRefreshListener() {
			public void refresh() {
				getRecentData(false);
			}
		});
		articleListView.addFooterView(LayoutInflater.from(this).inflate(R.layout.article_list_more, null));

		moreButton = (Button) findViewById(R.id.article_list_more);
		moreButton.setOnClickListener(this);

		refreshButton = (Button) findViewById(R.id.refresh);
		refreshButton.setOnClickListener(this);

		rightButton = (Button) findViewById(R.id.right_btn);
		rightButton.setText(R.string.refresh);
		rightButton.setOnClickListener(this);
	}

	private void showListView() {
		if (adapter.getCount() == 0) {
			if (!Statics.IS_SYNC_DATA) {
				emptyLayout.setVisibility(View.VISIBLE);
				noArticleListLayout.setVisibility(View.GONE);
			} else {
				noArticleListLayout.setVisibility(View.VISIBLE);
				emptyLayout.setVisibility(View.GONE);
			}
			articleListView.setVisibility(View.GONE);
		} else {
			emptyLayout.setVisibility(View.GONE);
			noArticleListLayout.setVisibility(View.GONE);
			articleListView.setVisibility(View.VISIBLE);
		}
	}

	private void initData() {
		List<Intro> list = new ListDao().query(0, Constants.LIST_PAGE_SIZE);
		adapter.setDataSources(list);
		adapter.notifyDataSetChanged();
		showListView();
		updateMinID(list);
		updateMaxID(list);
		if (isAutoRefresh && NetUtils.isNetAvailable()) {
			getRecentDataFromNet(true);
		}
	}

	// TODO 异步读取数据库
	private void getRecentData(boolean showProgressBar) {
		ListDao dao = new ListDao();
		int maxID = dao.queryMaxArticleID();
		if (maxID > curMaxID) {
			List<Intro> list = dao.queryRecentByArticleID(curMaxID, Constants.LIST_PAGE_SIZE);
			articleListView.refreshComplete();
			if (!list.isEmpty()) {
				adapter.insertBefore(list);
				adapter.notifyDataSetChanged();
				updateMaxID(list);
			}
		} else {
			getRecentDataFromNet(showProgressBar);
		}
	}

	private void updateDB(final ArrayList<Intro> list) {
		new Thread(new Runnable() {
			public void run() {
				new ListDao().insertNewRecord(list);
			}
		}).start();
	}

	/**
	 * 从网络获取文章列表
	 * 
	 * @param showProgressBar
	 *            是否需要展现进度条
	 */
	private void getRecentDataFromNet(final boolean showProgressBar) {
		Console.log("getRecentDataFromNet", showProgressBar);
		if (showProgressBar) {
			progressBarStrat(articleListView);
		}

		new ArticleListWraper(new BaseWraper.Callback() {
			@SuppressWarnings("unchecked")
			public void onSuccess(Object result) {
				Statics.IS_SYNC_DATA = true;
				ArrayList<Intro> list = (ArrayList<Intro>) result;
				articleListView.refreshComplete();
				if (!list.isEmpty()) {
					adapter.insertBefore(list);
					adapter.notifyDataSetChanged();
					updateDB(list);
					updateMaxID(list);
					if (showProgressBar) {
						updateMinID(list);
					}
				} else {
					showListView();
				}
				if (showProgressBar) {
					progressBarStop(articleListView, true);
				}
			}

			public void onFail(int errno, String errmsg) {
				String msg = (errmsg == null) ? ErrorUtils.getMsg(errno) : errmsg;
				Toast.makeText(ArticleListActivity.this, msg, 0).show();
				if (showProgressBar) {
					progressBarStop(articleListView, false);
				}
			}

		}).execute();
	}

	public void updateMinID(List<Intro> list) {
		curMinID = LogicUtils.getListMinID(list, curMinID);
	}

	public void updateMaxID(List<Intro> list) {
		curMaxID = LogicUtils.getListMaxID(list, curMaxID);
	}

	/**
	 * 先从本地查找，如果不足1页，从网络加载
	 */
	private void getEarlyData() {
		List<Intro> list = new ListDao().queryEarlyByArticleID(curMinID, Constants.LIST_PAGE_SIZE);
		if (list.size() < Constants.LIST_PAGE_SIZE) {
			getEarlyDataFromNet(curMinID);
		} else {
			adapter.insertAfter(list);
			adapter.notifyDataSetChanged();
			updateMinID(list);
		}
	}

	/**
	 * 从网络获取更多先前的数据
	 */
	private void getEarlyDataFromNet(int earlyArticleID) {
		if (earlyArticleID <= 0) {
			moreButton.setText(R.string.list_no_more);
			return;
		}

		moreButton.setText(R.string.loading);
		String query = HttpUtils.buildQuery(new String[] { "id", Statics.getUid() },
				new String[] { "last_id", String.valueOf(earlyArticleID) },
				new String[] { "token", Statics.getToken() });
		new ArticleListWraper(HttpUtils.buildURI(Constants.listUpdateEarlyIntfPath, query), new BaseWraper.Callback() {
			@SuppressWarnings("unchecked")
			public void onSuccess(Object result) {
				ArrayList<Intro> list = (ArrayList<Intro>) result;
				articleListView.refreshComplete();
				if (!list.isEmpty()) {
					adapter.insertAfter(list);
					adapter.notifyDataSetChanged();
					updateMinID(list);
					updateDB(list);
					moreButton.setText(R.string.list_more);
				} else {
					showListView();
					moreButton.setText(R.string.list_no_more);
				}
			}

			public void onFail(int errno, String errmsg) {
				String msg = (errmsg == null) ? ErrorUtils.getMsg(errno) : errmsg;
				Toast.makeText(ArticleListActivity.this, msg, 0).show();
			}
		}).execute();
	}

	class ArticleListAdapter extends BaseAdapter {
		private List<Intro> articleList;
		private LayoutInflater inflater;

		public ArticleListAdapter(Context context, ArrayList<Intro> list) {
			articleList = (list != null) ? list : new ArrayList<Intro>();
			inflater = LayoutInflater.from(context);
		}

		public void insertAfter(List<Intro> list) {
			if (!list.isEmpty()) {
				articleList.addAll(list);
			}
		}

		public void insertBefore(List<Intro> list) {
			if (!list.isEmpty()) {
				articleList.addAll(0, list);
			}
		}

		public ArrayList<Intro> getDataSources() {
			return articleList != null ? (ArrayList<Intro>) articleList : new ArrayList<Intro>();
		}

		public void setDataSources(List<Intro> list) {
			if (list == null) {
				list = new ArrayList<Intro>();
			}
			articleList = list;
		}

		public int getCount() {
			if (articleList == null) {
				return 0;
			}
			return articleList.size();
		}

		public Object getItem(int position) {
			if (articleList == null || position >= articleList.size() || position < 0) {
				return null;
			}
			return articleList.get(position);
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {

			ViewHolder holder = new ViewHolder();
			if (convertView == null) {
				convertView = inflater.inflate(R.layout.article_list_item, null);
				holder.time = (TextView) convertView.findViewById(R.id.article_item_time);
				holder.title = (TextView) convertView.findViewById(R.id.article_item_title);
				holder.intro = (TextView) convertView.findViewById(R.id.article_item_intro);
				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}

			Intro item = articleList.get(position);
			holder.id = item.id;
			holder.time.setText(item.time);
			holder.title.setText(item.title);
			holder.intro.setText(item.intro);

			return convertView;
		}

		class ViewHolder {
			public int id;
			public TextView time;
			public TextView title;
			public TextView intro;
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.main_menu_update:
			checkUpdate();
			break;
		case R.id.main_menu_download_offline:
			startOfflineDownload();
			break;
		case R.id.main_menu_setting:
			startActivity(new Intent(ArticleListActivity.this, SettingActivity.class));
			break;
		}
		return true;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			exit();
		}
		return super.onKeyDown(keyCode, event);
	}

}
